package com.dream.utils.web.tag;

import java.io.IOException;
import java.util.Locale;
import java.util.Map;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;

import org.apache.commons.lang.StringUtils;

import com.dream.utils.resource.i18n.MessageResourceUtils;
import com.dream.utils.resource.teamplate.TeamplateUtils;
import com.dream.utils.system.cfg.SystemConfigUtils;
import com.google.common.collect.Maps;

public class PagingTag extends BodyTagSupport {
	
	/** the message resources. */
	private static MessageResourceUtils mrUtils = MessageResourceUtils.getInstance();

	/** the Constant serialVersionUID. */
	private static final long serialVersionUID = 1L;
	
	private String formId;
	
	/** query the data **/
	private String function;

	/** the total data count **/
	private Long totalCount;

	/** whether show the total data count **/
	private boolean showTotalCount = true;

	/** whetehr show the page count **/
	private boolean showPageCount = true;

	/** paging variable context form **/
	private String context;
	
	/** default page size **/
	private static final int DEF_PAGE_SIZE ;
	
	/** max page size     **/
	private static final int MAX_PAGE_SIZE;
	
	private static String PAGING_FTL_PATH;
	
	static {
		DEF_PAGE_SIZE = SystemConfigUtils.instance().getInteger("system.pagesize.default", 10);
		MAX_PAGE_SIZE = SystemConfigUtils.instance().getInteger("system.pagesize.max", 100);
		PAGING_FTL_PATH = SystemConfigUtils.instance().getValue("paging.template.path", "paging/ftl/paging.ftl");
	}
	
	public String getFormId() {
		return formId;
	}

	public void setFormId(String formId) {
		this.formId = formId;
	}

	public void setFunction(String function) {
		this.function = function;
	}
	
	public void setTotalCount(Long totalCount) {
		this.totalCount = totalCount;
	}
	
	public void setshowTotalCount(boolean showTotalCount) {
		this.showTotalCount = showTotalCount;
	}
	
	public void setShowPageCount(boolean showPageCount) {
		this.showPageCount = showPageCount;
	}
	
	public void setContext(String context) {
		this.context = context;
	}
	
	private long getTotalCount() {

		if (totalCount == null) {
			totalCount = (Long) pageContext.getRequest().getAttribute("totalCount");
		}
		return totalCount == null ? 0L : totalCount.longValue();
	}
	
	private int getPageSize() throws JspException {
		
		int pageSize = DEF_PAGE_SIZE;
		String strPageSize = pageContext.getRequest().getParameter("pageSize");
		if (StringUtils.isNotBlank(strPageSize) ) {
			pageSize = Integer.parseInt(strPageSize);
		}
		if(pageSize<1 || pageSize > MAX_PAGE_SIZE){
			
			pageSize = DEF_PAGE_SIZE;
			
		}
		return pageSize;
	}
	
	private long getPageCount() throws JspException {
		
		long pages =(long) Math.ceil((double)getTotalCount() / getPageSize());

		return pages;
		
	}

	private long getCurrentPageIndex() throws JspException {
		
		long currentPageIndex = 1L;
		String page = pageContext.getRequest().getParameter("pageIndex");
		
		if (StringUtils.isNotBlank(page)) {
			currentPageIndex = Integer.parseInt(page);
		}
		
		if (currentPageIndex < 1L) {
			currentPageIndex = 1L;
		}
		
		if(currentPageIndex > getPageCount()){
			currentPageIndex = getPageCount();
		}
		return currentPageIndex;
	}
	
	@Override
	public int doEndTag() throws JspException {
		
		try {
			Locale locale = pageContext.getRequest().getLocale();
			long currentPageIndex = getCurrentPageIndex();
			long pageCount = getPageCount();
			long totalCount = getTotalCount();
			int pageSize = getPageSize();
			
			Map<String,Object> map = Maps.newHashMap();
			map.put("currentPageIndex", currentPageIndex);
			map.put("pageCount", pageCount);
			map.put("totalCount", totalCount);
			map.put("pageSize", pageSize);
			map.put("maxPageSize", MAX_PAGE_SIZE);
			map.put("function", function);
			map.put("showTotalCount", showTotalCount);
			map.put("showPageCount", showPageCount);
			map.put("context", context);
			if(StringUtils.isBlank(formId)){
				map.put("formId", "pagingForm");
			}else{
				map.put("formId", formId);
			}
			mrUtils.getMessage(locale, "page.haveNum");
			pageContext.getOut().print(TeamplateUtils.getContent(PAGING_FTL_PATH, map));
		} catch (IOException ex) {
			throw new JspException(ex);
		}
		return EVAL_PAGE;
	}

}
